iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Cloud Native

【하나, 둘, ready, get set, go】系列 第 27

【하나, 둘, ready, get set, go】Day 27 - 整合 GitLab CI 來達成自動化編譯多架構 Docker Image

  • 分享至 

  • xImage
  •  

前情提要

昨天我們透過手動下 docker build 來進行多架構 Docker Image 編譯

但身為懶人的我,肯定是要自動化的吧

所以今天就要來介紹如何透過 CI/CD 來達成這件事啦

這裡會使用 GitLab CI 來實作

實際操作

據說 GitLab CI 的執行環境是 x86_64 的 Docker 環境
所以說,如果是編譯 Docker Image 的話,預設會是編譯出 amd64 架構的 Docker Image

如果像是 Kubernetes 這種「容器化應用」的管理系統是安裝在 arm64 平台上的話
那 GitLab CI 預設編譯出來的 amd64 架構的 Docker Image 會是不能運行的喔~

(小聲說,之所以會寫編譯多架構 Docker Image 也是因為在 GitLab CI 這邊踩了坑😂)

.gitlab-ci.yml 撰寫

官方文件:GitLab CI 描述文件,.gitlab-ci.yml
https://docs.gitlab.com/ee/ci/yaml/

我們可以看到,GitLab 官方列出來的 CI pipeline Global Keywords (下圖)

GitLab CI pipeline Global Keywords

▲ 圖取自 GitLab Documentation

stages 設定

我們在這邊會用到的 Keywords 是 stages,用來定義在這個 pipeline 中總共會有哪些階段

在這邊,我們主要會有兩個 pipeline 階段

  1. 編譯 Go source code
  2. 編譯多架構 Docker Image
# Pipelines 中的所有執行階段
stages:
  # 編譯 Go source code
  - build-source-code
  
  # 編譯多架構 Docker Image
  - build-docker-image

stages:build-source-code

# 編譯 Go source code
build-code:
  # 執行階段
  stage: build-source-code

  # 要使用的 docker image
  image: golang:latest

  # 執行 Job 前要做的事
  before_script:
    # 檢查 go 的版本
    - go version
    - export GO111MODULE=on
    - export GIN_MODE=release

    # 建立 it15th 資料夾
    - mkdir -p ${CI_PROJECT_DIR}/

  script:
    - go build -o ${CI_PROJECT_DIR}/

stages:build-docker-image

# 透過 Docker-in-Docker 打包 Docker Image
build-image:
  # 執行階段
  stage: build-docker-image

  # 宣告區域變數
  variables:
    # Docker Image 名稱
    IMAGE_NAME: it15th

  # 要使用的 docker image
  image: docker:latest

  # 要使用的服務
  services:
    - docker:dind

  # 執行 Job 前要做的事
  before_script:
    # 查看 docker buildx 的版本
    - docker buildx version

    # 查看 docker buildx 有哪些架構可以用
    - docker buildx inspect --bootstrap

    # 登入 Docker Hub
    - echo "$DOCKERHUB_PWD" | docker login -u $DOCKERHUB_USERNAME --password-stdin

  script:
    # 建立一個 docker buildx builder 實例
    # 使用 docker-container driver 並使用這個 builder 實例
    - docker buildx create --name it15thBuilder --driver docker-container --use

    # 透過上面建出來的 builder 不使用快取來編譯多架構 Docker Image
    # 預設使用 Dockerfile 來編譯
    # 指定系統架構為 linux/amd64、linux/arm64
    # 編譯完成後加上 latest tag 推上 Docker Hub
    - docker buildx build --push --no-cache -t $DOCKERHUB_USERNAME/$IMAGE_NAME:latest $CI_PROJECT_DIR/ --platform linux/amd64,linux/arm64

    # 上傳到 Docker Hub 後移除 it15thBuilder 這個 builder 實例
    - docker buildx rm it15thBuilder

Final

我們的 .gitlab-ci.yml 最終就會變成下面這樣啦

# Pipelines 中的所有執行階段
stages:
  # 編譯 Go source code
  - build-source-code

  # 透過 Docker-in-Docker 打包多架構 Docker Image
  - build-docker-image

# 編譯 Go source code
build-code:
  # 執行階段
  stage: build-source-code

  # 要使用的 docker image
  image: golang:latest

  # 執行 Job 前要做的事
  before_script:
    # 檢查 go 的版本
    - go version
    - export GO111MODULE=on
    - export GIN_MODE=release

    # 建立 it15th 資料夾
    - mkdir -p ${CI_PROJECT_DIR}/

  script:
    - go build -o ${CI_PROJECT_DIR}/

# 透過 Docker-in-Docker 打包 Docker Image
build-image:
  # 執行階段
  stage: build-docker-image

  # 宣告區域變數
  variables:
    # Docker Image 名稱
    IMAGE_NAME: it15th

  # 要使用的 docker image
  image: docker:latest

  # 要使用的服務
  services:
    - docker:dind

  # 執行 Job 前要做的事
  before_script:
    # 查看 docker buildx 的版本
    - docker buildx version

    # 查看 docker buildx 有哪些架構可以用
    - docker buildx inspect --bootstrap

    # 登入 Docker Hub
    - echo "$DOCKERHUB_PWD" | docker login -u $DOCKERHUB_USERNAME --password-stdin

  script:
    # 建立一個 docker buildx builder 實例
    # 使用 docker-container driver 並使用這個 builder 實例
    - docker buildx create --name it15thBuilder --driver docker-container --use

    # 透過上面建出來的 builder 不使用快取來編譯多架構 Docker Image
    # 預設使用 Dockerfile 來編譯
    # 指定系統架構為 linux/amd64、linux/arm64
    # 編譯完成後加上 latest tag 推上 Docker Hub
    - docker buildx build --push --no-cache -t $DOCKERHUB_USERNAME/$IMAGE_NAME:latest $CI_PROJECT_DIR/ --platform linux/amd64,linux/arm64

    # 上傳到 Docker Hub 後移除 it15thBuilder 這個 builder 實例
    - docker buildx rm it15thBuilder

總結

透過 GitLab CI 自動化編譯多架構 Docker Image

成功讓我們可以不用手動輸入 docker build 編譯

這樣日後就只要將 Code Commit 到 Git Repo 後,就會自動透過 GitLab CI 開始編譯多架構 Docker Image 了

明天就要來將編譯好的 Docker Image 透過 Kubernetes 來執行啦

明天見~


上一篇
【하나, 둘, ready, get set, go】Day 26 - 將服務打包成多架構 Docker Image
下一篇
【하나, 둘, ready, get set, go】Day 28 - 將服務部署上 Kubernetes 上吧 feat. minikube
系列文
【하나, 둘, ready, get set, go】30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言